Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Displaying Raw • Download


RNS/Channel.py HEAD (3535327f) Text, 26.51 KB

T8b949e# Reticulum License
T8b949e#
T8b949e# Copyright (c) 2016-2025 Mark Qvist
T8b949e#
T8b949e# Permission is hereby granted, free of charge, to any person obtaining a copy
T8b949e# of this software and associated documentation files (the "Software"), to deal
T8b949e# in the Software without restriction, including without limitation the rights
T8b949e# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
T8b949e# copies of the Software, and to permit persons to whom the Software is
T8b949e# furnished to do so, subject to the following conditions:
T8b949e#
T8b949e# - The Software shall not be used in any kind of system which includes amongst
T8b949e# its functions the ability to purposefully do harm to human beings.
T8b949e#
T8b949e# - The Software shall not be used, directly or indirectly, in the creation of
T8b949e# an artificial intelligence, machine learning or language model training
T8b949e# dataset, including but not limited to any use that contributes to the
T8b949e# training or development of such a model or algorithm.
T8b949e#
T8b949e# - The above copyright notice and this permission notice shall be included in
T8b949e# all copies or substantial portions of the Software.
T8b949e#
T8b949e# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
T8b949e# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
T8b949e# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
T8b949e# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
T8b949e# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
T8b949e# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
T8b949e# SOFTWARE.

Tff7b72from T7ee787__future__ Tff7b72import Te6edf3annotations
Tff7b72import T7ee787collections
Tff7b72import T7ee787enum
Tff7b72import T7ee787threading
Tff7b72import T7ee787time
Tff7b72from T7ee787types Tff7b72import Te6edf3TracebackType
Tff7b72from T7ee787typing Tff7b72import Te6edf3TypeTb4b4b4, Te6edf3CallableTb4b4b4, Te6edf3TypeVarTb4b4b4, Te6edf3GenericTb4b4b4, Te6edf3NewType
Tff7b72import T7ee787abc
Tff7b72import T7ee787contextlib
Tff7b72import T7ee787struct
Tff7b72import T7ee787RNS
Tff7b72from T7ee787abc Tff7b72import Te6edf3ABCTb4b4b4, Te6edf3abstractmethod
Te6edf3TPacket Tff7b72= Te6edf3TypeVarTb4b4b4(Ta5d6ff"Ta5d6ffTPacketTa5d6ff"Tb4b4b4)

Tff7b72class T56d364SystemMessageTypesTb4b4b4(Te6edf3enumTff7b72.Td2a8ffIntEnumTb4b4b4)Tb4b4b4:
Te6edf3SMT_STREAM_DATA Tff7b72= T79c0ff0xff00

Tff7b72class T56d364ChannelOutletBaseTb4b4b4(Te6edf3ABCTb4b4b4, Te6edf3GenericTb4b4b4[Te6edf3TPacketTb4b4b4]Tb4b4b4)Tb4b4b4:
T8b949e"""
An abstract transport layer interface used by Channel.

DEPRECATED: This was created for testing; eventually
Channel will use Link or a LinkBase interface
directly.
"""
Tf0883e@abstractmethod
Tff7b72def Td2a8ffsendTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3rawTb4b4b4: Tffa657bytesTb4b4b4) Tff7b72-Tff7b72> Te6edf3TPacketTb4b4b4:
Tff7b72raise Tff7b72NotImplementedTb4b4b4(Tb4b4b4)

Tf0883e@abstractmethod
Tff7b72def Td2a8ffresendTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3packetTb4b4b4: Te6edf3TPacketTb4b4b4) Tff7b72-Tff7b72> Te6edf3TPacketTb4b4b4:
Tff7b72raise Tff7b72NotImplementedTb4b4b4(Tb4b4b4)

Tf0883e@property
Tf0883e@abstractmethod
Tff7b72def Td2a8ffmduTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72raise Tff7b72NotImplementedTb4b4b4(Tb4b4b4)

Tf0883e@property
Tf0883e@abstractmethod
Tff7b72def Td2a8ffrttTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72raise Tff7b72NotImplementedTb4b4b4(Tb4b4b4)

Tf0883e@property
Tf0883e@abstractmethod
Tff7b72def Td2a8ffis_usableTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72raise Tff7b72NotImplementedTb4b4b4(Tb4b4b4)

Tf0883e@abstractmethod
Tff7b72def Td2a8ffget_packet_stateTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3packetTb4b4b4: Te6edf3TPacketTb4b4b4) Tff7b72-Tff7b72> Te6edf3MessageStateTb4b4b4:
Tff7b72raise Tff7b72NotImplementedTb4b4b4(Tb4b4b4)

Tf0883e@abstractmethod
Tff7b72def Td2a8fftimed_outTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72raise Tff7b72NotImplementedTb4b4b4(Tb4b4b4)

Tf0883e@abstractmethod
Tff7b72def Tff7b72__str__Tb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72raise Tff7b72NotImplementedTb4b4b4(Tb4b4b4)

Tf0883e@abstractmethod
Tff7b72def Td2a8ffset_packet_timeout_callbackTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3packetTb4b4b4: Te6edf3TPacketTb4b4b4, Te6edf3callbackTb4b4b4: Te6edf3CallableTb4b4b4[Tb4b4b4[Te6edf3TPacketTb4b4b4]Tb4b4b4, Tff7b72NoneTb4b4b4] Tff7b72| Tff7b72NoneTb4b4b4,
Te6edf3timeoutTb4b4b4: Tffa657float Tff7b72| Tff7b72None Tff7b72= Tff7b72NoneTb4b4b4)Tb4b4b4:
Tff7b72raise Tff7b72NotImplementedTb4b4b4(Tb4b4b4)

Tf0883e@abstractmethod
Tff7b72def Td2a8ffset_packet_delivered_callbackTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3packetTb4b4b4: Te6edf3TPacketTb4b4b4, Te6edf3callbackTb4b4b4: Te6edf3CallableTb4b4b4[Tb4b4b4[Te6edf3TPacketTb4b4b4]Tb4b4b4, Tff7b72NoneTb4b4b4] Tff7b72| Tff7b72NoneTb4b4b4)Tb4b4b4:
Tff7b72raise Tff7b72NotImplementedTb4b4b4(Tb4b4b4)

Tf0883e@abstractmethod
Tff7b72def Td2a8ffget_packet_idTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3packetTb4b4b4: Te6edf3TPacketTb4b4b4) Tff7b72-Tff7b72> Tffa657anyTb4b4b4:
Tff7b72raise Tff7b72NotImplementedTb4b4b4(Tb4b4b4)


Tff7b72class T56d364CETypeTb4b4b4(Te6edf3enumTff7b72.Td2a8ffIntEnumTb4b4b4)Tb4b4b4:
T8b949e"""
ChannelException type codes
"""
Te6edf3ME_NO_MSG_TYPE Tff7b72= T79c0ff0
Te6edf3ME_INVALID_MSG_TYPE Tff7b72= T79c0ff1
Te6edf3ME_NOT_REGISTERED Tff7b72= T79c0ff2
Te6edf3ME_LINK_NOT_READY Tff7b72= T79c0ff3
Te6edf3ME_ALREADY_SENT Tff7b72= T79c0ff4
Te6edf3ME_TOO_BIG Tff7b72= T79c0ff5


Tff7b72class T56d364ChannelExceptionTb4b4b4(Tf85149ExceptionTb4b4b4)Tb4b4b4:
T8b949e"""
An exception thrown by Channel, with a type code.
"""
Tff7b72def Tff7b72__init__Tb4b4b4(Tff7b72selfTb4b4b4, Te6edf3ce_typeTb4b4b4: Te6edf3CETypeTb4b4b4, Tff7b72*Te6edf3argsTb4b4b4)Tb4b4b4:
Tffa657superTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ff__init__Tb4b4b4(Te6edf3argsTb4b4b4)
Tff7b72selfTff7b72.Td2a8fftype Tff7b72= Te6edf3ce_type


Tff7b72class T56d364MessageStateTb4b4b4(Te6edf3enumTff7b72.Td2a8ffIntEnumTb4b4b4)Tb4b4b4:
T8b949e"""
Set of possible states for a Message
"""
Te6edf3MSGSTATE_NEW Tff7b72= T79c0ff0
Te6edf3MSGSTATE_SENT Tff7b72= T79c0ff1
Te6edf3MSGSTATE_DELIVERED Tff7b72= T79c0ff2
Te6edf3MSGSTATE_FAILED Tff7b72= T79c0ff3


Tff7b72class T56d364MessageBaseTb4b4b4(Te6edf3abcTff7b72.Td2a8ffABCTb4b4b4)Tb4b4b4:
T8b949e"""
Base type for any messages sent or received on a Channel.
Subclasses must define the two abstract methods as well as
the ``MSGTYPE`` class variable.
"""
T8b949e# MSGTYPE must be unique within all classes sent over a
T8b949e# channel. Additionally, MSGTYPE > 0xf000 are reserved.
Te6edf3MSGTYPE Tff7b72= Tff7b72None
T8b949e"""
Defines a unique identifier for a message class.
* Must be unique within all classes registered with a ``Channel``
* Must be less than ``0xf000``. Values greater than or equal to ``0xf000`` are reserved.
"""

Tf0883e@abstractmethod
Tff7b72def Td2a8ffpackTb4b4b4(Tff7b72selfTb4b4b4) Tff7b72-Tff7b72> Tffa657bytesTb4b4b4:
T8b949e"""
Create and return the binary representation of the message

:return: binary representation of message
"""
Tff7b72raise Tff7b72NotImplementedTb4b4b4(Tb4b4b4)

Tf0883e@abstractmethod
Tff7b72def Td2a8ffunpackTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3rawTb4b4b4: Tffa657bytesTb4b4b4)Tb4b4b4:
T8b949e"""
Populate message from binary representation

:param raw: binary representation
"""
Tff7b72raise Tff7b72NotImplementedTb4b4b4(Tb4b4b4)


Te6edf3MessageCallbackType Tff7b72= Te6edf3NewTypeTb4b4b4(Ta5d6ff"Ta5d6ffMessageCallbackTypeTa5d6ff"Tb4b4b4, Te6edf3CallableTb4b4b4[Tb4b4b4[Te6edf3MessageBaseTb4b4b4]Tb4b4b4, Tffa657boolTb4b4b4]Tb4b4b4)


Tff7b72class T56d364EnvelopeTb4b4b4:
T8b949e"""
Internal wrapper used to transport messages over a channel and
track its state within the channel framework.
"""
Tff7b72def Td2a8ffunpackTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3message_factoriesTb4b4b4: Tffa657dictTb4b4b4[Tffa657intTb4b4b4, Te6edf3TypeTb4b4b4]Tb4b4b4) Tff7b72-Tff7b72> Te6edf3MessageBaseTb4b4b4:
Te6edf3msgtypeTb4b4b4, Tff7b72selfTff7b72.Td2a8ffsequenceTb4b4b4, Te6edf3length Tff7b72= Te6edf3structTff7b72.Td2a8ffunpackTb4b4b4(Ta5d6ff"Ta5d6ff>HHHTa5d6ff"Tb4b4b4, Tff7b72selfTff7b72.Td2a8ffrawTb4b4b4[Tb4b4b4:T79c0ff6Tb4b4b4]Tb4b4b4)
Te6edf3raw Tff7b72= Tff7b72selfTff7b72.Td2a8ffrawTb4b4b4[T79c0ff6Tb4b4b4:Tb4b4b4]
Te6edf3ctor Tff7b72= Te6edf3message_factoriesTff7b72.Td2a8ffgetTb4b4b4(Te6edf3msgtypeTb4b4b4, Tff7b72NoneTb4b4b4)
Tff7b72if Te6edf3ctor Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72raise Te6edf3ChannelExceptionTb4b4b4(Te6edf3CETypeTff7b72.Td2a8ffME_NOT_REGISTEREDTb4b4b4, Ta5d6fffTa5d6ff"Ta5d6ffUnable to find constructor for Channel MSGTYPE Tffd700{Tffa657hexTb4b4b4(Te6edf3msgtypeTb4b4b4)Tffd700}Ta5d6ff"Tb4b4b4)
Te6edf3message Tff7b72= Te6edf3ctorTb4b4b4(Tb4b4b4)
Te6edf3messageTff7b72.Td2a8ffunpackTb4b4b4(Te6edf3rawTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffunpacked Tff7b72= Tff7b72True
Tff7b72selfTff7b72.Td2a8ffmessage Tff7b72= Te6edf3message

Tff7b72return Te6edf3message

Tff7b72def Td2a8ffpackTb4b4b4(Tff7b72selfTb4b4b4) Tff7b72-Tff7b72> Tffa657bytesTb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffmessageTff7b72.Td2a8ff__class__Tff7b72.Td2a8ffMSGTYPE Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72raise Te6edf3ChannelExceptionTb4b4b4(Te6edf3CETypeTff7b72.Td2a8ffME_NO_MSG_TYPETb4b4b4, Ta5d6fffTa5d6ff"Tffd700{Tff7b72selfTff7b72.Td2a8ffmessageTff7b72.Td2a8ff__class__Tffd700}Ta5d6ff lacks MSGTYPETa5d6ff"Tb4b4b4)
Te6edf3data Tff7b72= Tff7b72selfTff7b72.Td2a8ffmessageTff7b72.Td2a8ffpackTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffraw Tff7b72= Te6edf3structTff7b72.Td2a8ffpackTb4b4b4(Ta5d6ff"Ta5d6ff>HHHTa5d6ff"Tb4b4b4, Tff7b72selfTff7b72.Td2a8ffmessageTff7b72.Td2a8ffMSGTYPETb4b4b4, Tff7b72selfTff7b72.Td2a8ffsequenceTb4b4b4, Tffa657lenTb4b4b4(Te6edf3dataTb4b4b4)Tb4b4b4) Tff7b72+ Te6edf3data
Tff7b72selfTff7b72.Td2a8ffpacked Tff7b72= Tff7b72True
Tff7b72return Tff7b72selfTff7b72.Td2a8ffraw

Tff7b72def Tff7b72__init__Tb4b4b4(Tff7b72selfTb4b4b4, Te6edf3outletTb4b4b4: Te6edf3ChannelOutletBaseTb4b4b4, Te6edf3messageTb4b4b4: Te6edf3MessageBase Tff7b72= Tff7b72NoneTb4b4b4, Te6edf3rawTb4b4b4: Tffa657bytes Tff7b72= Tff7b72NoneTb4b4b4, Te6edf3sequenceTb4b4b4: Tffa657int Tff7b72= Tff7b72NoneTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffts Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffid Tff7b72= Tffa657idTb4b4b4(Tff7b72selfTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmessage Tff7b72= Te6edf3message
Tff7b72selfTff7b72.Td2a8ffraw Tff7b72= Te6edf3raw
Tff7b72selfTff7b72.Td2a8ffpacketTb4b4b4: Te6edf3TPacket Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffsequence Tff7b72= Te6edf3sequence
Tff7b72selfTff7b72.Td2a8ffoutlet Tff7b72= Te6edf3outlet
Tff7b72selfTff7b72.Td2a8fftries Tff7b72= T79c0ff0
Tff7b72selfTff7b72.Td2a8ffunpacked Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ffpacked Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8fftracked Tff7b72= Tff7b72False


Tff7b72class T56d364ChannelTb4b4b4(Te6edf3contextlibTff7b72.Td2a8ffAbstractContextManagerTb4b4b4)Tb4b4b4:
T8b949e"""
Provides reliable delivery of messages over
a link.

``Channel`` differs from ``Request`` and
``Resource`` in some important ways:

**Continuous**
Messages can be sent or received as long as
the ``Link`` is open.
**Bi-directional**
Messages can be sent in either direction on
the ``Link``; neither end is the client or
server.
**Size-constrained**
Messages must be encoded into a single packet.

``Channel`` is similar to ``Packet``, except that it
provides reliable delivery (automatic retries) as well
as a structure for exchanging several types of
messages over the ``Link``.

``Channel`` is not instantiated directly, but rather
obtained from a ``Link`` with ``get_channel()``.
"""

T8b949e# The initial window size at channel setup
Te6edf3WINDOW Tff7b72= T79c0ff2

T8b949e# Absolute minimum window size
Te6edf3WINDOW_MIN Tff7b72= T79c0ff2
Te6edf3WINDOW_MIN_LIMIT_SLOW Tff7b72= T79c0ff2
Te6edf3WINDOW_MIN_LIMIT_MEDIUM Tff7b72= T79c0ff5
Te6edf3WINDOW_MIN_LIMIT_FAST Tff7b72= T79c0ff16

T8b949e# The maximum window size for transfers on slow links
Te6edf3WINDOW_MAX_SLOW Tff7b72= T79c0ff5

T8b949e# The maximum window size for transfers on mid-speed links
Te6edf3WINDOW_MAX_MEDIUM Tff7b72= T79c0ff12

T8b949e# The maximum window size for transfers on fast links
Te6edf3WINDOW_MAX_FAST Tff7b72= T79c0ff48
T8b949e# For calculating maps and guard segments, this
T8b949e# must be set to the global maximum window.
Te6edf3WINDOW_MAX Tff7b72= Te6edf3WINDOW_MAX_FAST
T8b949e# If the fast rate is sustained for this many request
T8b949e# rounds, the fast link window size will be allowed.
Te6edf3FAST_RATE_THRESHOLD Tff7b72= T79c0ff10

T8b949e# If the RTT rate is higher than this value,
T8b949e# the max window size for fast links will be used.
Te6edf3RTT_FAST Tff7b72= T79c0ff0.18
Te6edf3RTT_MEDIUM Tff7b72= T79c0ff0.75
Te6edf3RTT_SLOW Tff7b72= T79c0ff1.45

T8b949e# The minimum allowed flexibility of the window size.
T8b949e# The difference between window_max and window_min
T8b949e# will never be smaller than this value.
Te6edf3WINDOW_FLEXIBILITY Tff7b72= T79c0ff4

Te6edf3SEQ_MAX Tff7b72= T79c0ff0xFFFF
Te6edf3SEQ_MODULUS Tff7b72= Te6edf3SEQ_MAXTff7b72+T79c0ff1

Tff7b72def Tff7b72__init__Tb4b4b4(Tff7b72selfTb4b4b4, Te6edf3outletTb4b4b4: Te6edf3ChannelOutletBaseTb4b4b4)Tb4b4b4:
T8b949e"""

@param outlet:
"""
Tff7b72selfTff7b72.Td2a8ff_outlet Tff7b72= Te6edf3outlet
Tff7b72selfTff7b72.Td2a8ff_lock Tff7b72= Te6edf3threadingTff7b72.Td2a8ffRLockTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_tx_ringTb4b4b4: Te6edf3collectionsTff7b72.Td2a8ffdequeTb4b4b4[Te6edf3EnvelopeTb4b4b4] Tff7b72= Te6edf3collectionsTff7b72.Td2a8ffdequeTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_rx_ringTb4b4b4: Te6edf3collectionsTff7b72.Td2a8ffdequeTb4b4b4[Te6edf3EnvelopeTb4b4b4] Tff7b72= Te6edf3collectionsTff7b72.Td2a8ffdequeTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_message_callbacksTb4b4b4: Tb4b4b4[Te6edf3MessageCallbackTypeTb4b4b4] Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72selfTff7b72.Td2a8ff_next_sequence Tff7b72= T79c0ff0
Tff7b72selfTff7b72.Td2a8ff_next_rx_sequence Tff7b72= T79c0ff0
Tff7b72selfTff7b72.Td2a8ff_message_factoriesTb4b4b4: Tffa657dictTb4b4b4[Tffa657intTb4b4b4, Te6edf3TypeTb4b4b4[Te6edf3MessageBaseTb4b4b4]Tb4b4b4] Tff7b72= Tb4b4b4{Tb4b4b4}
Tff7b72selfTff7b72.Td2a8ff_max_tries Tff7b72= T79c0ff5
Tff7b72selfTff7b72.Td2a8fffast_rate_rounds Tff7b72= T79c0ff0
Tff7b72selfTff7b72.Td2a8ffmedium_rate_rounds Tff7b72= T79c0ff0

Tff7b72if Tff7b72selfTff7b72.Td2a8ff_outletTff7b72.Td2a8ffrtt Tff7b72> Te6edf3ChannelTff7b72.Td2a8ffRTT_SLOWTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffwindow Tff7b72= T79c0ff1
Tff7b72selfTff7b72.Td2a8ffwindow_max Tff7b72= T79c0ff1
Tff7b72selfTff7b72.Td2a8ffwindow_min Tff7b72= T79c0ff1
Tff7b72selfTff7b72.Td2a8ffwindow_flexibility Tff7b72= T79c0ff1
Tff7b72elseTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffwindow Tff7b72= Te6edf3ChannelTff7b72.Td2a8ffWINDOW
Tff7b72selfTff7b72.Td2a8ffwindow_max Tff7b72= Te6edf3ChannelTff7b72.Td2a8ffWINDOW_MAX_SLOW
Tff7b72selfTff7b72.Td2a8ffwindow_min Tff7b72= Te6edf3ChannelTff7b72.Td2a8ffWINDOW_MIN
Tff7b72selfTff7b72.Td2a8ffwindow_flexibility Tff7b72= Te6edf3ChannelTff7b72.Td2a8ffWINDOW_FLEXIBILITY

Tff7b72def Tff7b72__enter__Tb4b4b4(Tff7b72selfTb4b4b4) Tff7b72-Tff7b72> Te6edf3ChannelTb4b4b4:
Tff7b72return Tff7b72self

Tff7b72def Tff7b72__exit__Tb4b4b4(Tff7b72selfTb4b4b4, Te6edf3__exc_typeTb4b4b4: Te6edf3TypeTb4b4b4[Tf85149BaseExceptionTb4b4b4] Tff7b72| Tff7b72NoneTb4b4b4, Te6edf3__exc_valueTb4b4b4: Tf85149BaseException Tff7b72| Tff7b72NoneTb4b4b4,
Te6edf3__tracebackTb4b4b4: Te6edf3TracebackType Tff7b72| Tff7b72NoneTb4b4b4) Tff7b72-Tff7b72> Tffa657bool Tff7b72| Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_shutdownTb4b4b4(Tb4b4b4)
Tff7b72return Tff7b72False

Tff7b72def Td2a8ffregister_message_typeTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3message_classTb4b4b4: Te6edf3TypeTb4b4b4[Te6edf3MessageBaseTb4b4b4]Tb4b4b4)Tb4b4b4:
T8b949e"""
Register a message class for reception over a ``Channel``.

Message classes must extend ``MessageBase``.

:param message_class: Class to register
"""
Tff7b72selfTff7b72.Td2a8ff_register_message_typeTb4b4b4(Te6edf3message_classTb4b4b4, Te6edf3is_system_typeTff7b72=Tff7b72FalseTb4b4b4)

Tff7b72def Td2a8ff_register_message_typeTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3message_classTb4b4b4: Te6edf3TypeTb4b4b4[Te6edf3MessageBaseTb4b4b4]Tb4b4b4, Tff7b72*Tb4b4b4, Te6edf3is_system_typeTb4b4b4: Tffa657bool Tff7b72= Tff7b72FalseTb4b4b4)Tb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72if Tff7b72not Tffa657issubclassTb4b4b4(Te6edf3message_classTb4b4b4, Te6edf3MessageBaseTb4b4b4)Tb4b4b4:
Tff7b72raise Te6edf3ChannelExceptionTb4b4b4(Te6edf3CETypeTff7b72.Td2a8ffME_INVALID_MSG_TYPETb4b4b4,
Ta5d6fffTa5d6ff"Tffd700{Te6edf3message_classTffd700}Ta5d6ff is not a subclass of Tffd700{Te6edf3MessageBaseTffd700}Ta5d6ff.Ta5d6ff"Tb4b4b4)
Tff7b72if Te6edf3message_classTff7b72.Td2a8ffMSGTYPE Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72raise Te6edf3ChannelExceptionTb4b4b4(Te6edf3CETypeTff7b72.Td2a8ffME_INVALID_MSG_TYPETb4b4b4,
Ta5d6fffTa5d6ff"Tffd700{Te6edf3message_classTffd700}Ta5d6ff has invalid MSGTYPE class attribute.Ta5d6ff"Tb4b4b4)
Tff7b72if Te6edf3message_classTff7b72.Td2a8ffMSGTYPE Tff7b72>Tff7b72= T79c0ff0xf000 Tff7b72and Tff7b72not Te6edf3is_system_typeTb4b4b4:
Tff7b72raise Te6edf3ChannelExceptionTb4b4b4(Te6edf3CETypeTff7b72.Td2a8ffME_INVALID_MSG_TYPETb4b4b4,
Ta5d6fffTa5d6ff"Tffd700{Te6edf3message_classTffd700}Ta5d6ff has system-reserved message type.Ta5d6ff"Tb4b4b4)
Tff7b72tryTb4b4b4:
Te6edf3message_classTb4b4b4(Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3exTb4b4b4:
Tff7b72raise Te6edf3ChannelExceptionTb4b4b4(Te6edf3CETypeTff7b72.Td2a8ffME_INVALID_MSG_TYPETb4b4b4,
Ta5d6fffTa5d6ff"Tffd700{Te6edf3message_classTffd700}Ta5d6ff raised an exception when constructed with no arguments: Tffd700{Te6edf3exTffd700}Ta5d6ff"Tb4b4b4)

Tff7b72selfTff7b72.Td2a8ff_message_factoriesTb4b4b4[Te6edf3message_classTff7b72.Td2a8ffMSGTYPETb4b4b4] Tff7b72= Te6edf3message_class

Tff7b72def Td2a8ffadd_message_handlerTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3callbackTb4b4b4: Te6edf3MessageCallbackTypeTb4b4b4)Tb4b4b4:
T8b949e"""
Add a handler for incoming messages. A handler
has the following signature:

``(message: MessageBase) -> bool``

Handlers are processed in the order they are
added. If any handler returns True, processing
of the message stops; handlers after the
returning handler will not be called.

:param callback: Function to call
"""
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72if Te6edf3callback Tff7b72not Tff7b72in Tff7b72selfTff7b72.Td2a8ff_message_callbacksTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_message_callbacksTff7b72.Td2a8ffappendTb4b4b4(Te6edf3callbackTb4b4b4)

Tff7b72def Td2a8ffremove_message_handlerTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3callbackTb4b4b4: Te6edf3MessageCallbackTypeTb4b4b4)Tb4b4b4:
T8b949e"""
Remove a handler added with ``add_message_handler``.

:param callback: handler to remove
"""
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72if Te6edf3callback Tff7b72in Tff7b72selfTff7b72.Td2a8ff_message_callbacksTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_message_callbacksTff7b72.Td2a8ffremoveTb4b4b4(Te6edf3callbackTb4b4b4)

Tff7b72def Td2a8ff_shutdownTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_message_callbacksTff7b72.Td2a8ffclearTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_clear_ringsTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ff_clear_ringsTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72for Te6edf3envelope Tff7b72in Tff7b72selfTff7b72.Td2a8ff_tx_ringTb4b4b4:
Tff7b72if Te6edf3envelopeTff7b72.Td2a8ffpacket Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_outletTff7b72.Td2a8ffset_packet_timeout_callbackTb4b4b4(Te6edf3envelopeTff7b72.Td2a8ffpacketTb4b4b4, Tff7b72NoneTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_outletTff7b72.Td2a8ffset_packet_delivered_callbackTb4b4b4(Te6edf3envelopeTff7b72.Td2a8ffpacketTb4b4b4, Tff7b72NoneTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_tx_ringTff7b72.Td2a8ffclearTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_rx_ringTff7b72.Td2a8ffclearTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ff_emplace_envelopeTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3envelopeTb4b4b4: Te6edf3EnvelopeTb4b4b4, Te6edf3ringTb4b4b4: Te6edf3collectionsTff7b72.Td2a8ffdequeTb4b4b4[Te6edf3EnvelopeTb4b4b4]Tb4b4b4) Tff7b72-Tff7b72> Tffa657boolTb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Te6edf3i Tff7b72= T79c0ff0
Tff7b72for Te6edf3existing Tff7b72in Te6edf3ringTb4b4b4:

Tff7b72if Te6edf3envelopeTff7b72.Td2a8ffsequence Tff7b72== Te6edf3existingTff7b72.Td2a8ffsequenceTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffEnvelope: Emplacement of duplicate envelope with sequence Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3envelopeTff7b72.Td2a8ffsequenceTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_EXTREMETb4b4b4)
Tff7b72return Tff7b72False
Tff7b72if Te6edf3envelopeTff7b72.Td2a8ffsequence Tff7b72< Te6edf3existingTff7b72.Td2a8ffsequence Tff7b72and Tff7b72not Tb4b4b4(Tff7b72selfTff7b72.Td2a8ff_next_rx_sequence Tff7b72- Te6edf3envelopeTff7b72.Td2a8ffsequenceTb4b4b4) Tff7b72> Tb4b4b4(Te6edf3ChannelTff7b72.Td2a8ffSEQ_MAXTff7b72/Tff7b72/T79c0ff2Tb4b4b4)Tb4b4b4:
Te6edf3ringTff7b72.Td2a8ffinsertTb4b4b4(Te6edf3iTb4b4b4, Te6edf3envelopeTb4b4b4)

Te6edf3envelopeTff7b72.Td2a8fftracked Tff7b72= Tff7b72True
Tff7b72return Tff7b72True
Te6edf3i Tff7b72+Tff7b72= T79c0ff1
Te6edf3envelopeTff7b72.Td2a8fftracked Tff7b72= Tff7b72True
Te6edf3ringTff7b72.Td2a8ffappendTb4b4b4(Te6edf3envelopeTb4b4b4)

Tff7b72return Tff7b72True

Tff7b72def Td2a8ff_run_callbacksTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3messageTb4b4b4: Te6edf3MessageBaseTb4b4b4)Tb4b4b4:
Te6edf3cbs Tff7b72= Tff7b72selfTff7b72.Td2a8ff_message_callbacksTff7b72.Td2a8ffcopyTb4b4b4(Tb4b4b4)

Tff7b72for Te6edf3cb Tff7b72in Te6edf3cbsTb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72if Te6edf3cbTb4b4b4(Te6edf3messageTb4b4b4)Tb4b4b4:
Tff7b72return
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffChannel Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff experienced an error while running a message callback. The contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Tff7b72def Td2a8ff_receiveTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3rawTb4b4b4: Tffa657bytesTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3envelope Tff7b72= Te6edf3EnvelopeTb4b4b4(Te6edf3outletTff7b72=Tff7b72selfTff7b72.Td2a8ff_outletTb4b4b4, Te6edf3rawTff7b72=Te6edf3rawTb4b4b4)
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Te6edf3message Tff7b72= Te6edf3envelopeTff7b72.Td2a8ffunpackTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_message_factoriesTb4b4b4)

Tff7b72if Te6edf3envelopeTff7b72.Td2a8ffsequence Tff7b72< Tff7b72selfTff7b72.Td2a8ff_next_rx_sequenceTb4b4b4:
Te6edf3window_overflow Tff7b72= Tb4b4b4(Tff7b72selfTff7b72.Td2a8ff_next_rx_sequenceTff7b72+Te6edf3ChannelTff7b72.Td2a8ffWINDOW_MAXTb4b4b4) Tff7b72% Te6edf3ChannelTff7b72.Td2a8ffSEQ_MODULUS
Tff7b72if Te6edf3window_overflow Tff7b72< Tff7b72selfTff7b72.Td2a8ff_next_rx_sequenceTb4b4b4:
Tff7b72if Te6edf3envelopeTff7b72.Td2a8ffsequence Tff7b72> Te6edf3window_overflowTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffInvalid packet sequence (Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3envelopeTff7b72.Td2a8ffsequenceTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff) received on channel Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_EXTREMETb4b4b4)
Tff7b72return
Tff7b72elseTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffInvalid packet sequence (Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3envelopeTff7b72.Td2a8ffsequenceTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff) received on channel Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_EXTREMETb4b4b4)
Tff7b72return

Te6edf3is_new Tff7b72= Tff7b72selfTff7b72.Td2a8ff_emplace_envelopeTb4b4b4(Te6edf3envelopeTb4b4b4, Tff7b72selfTff7b72.Td2a8ff_rx_ringTb4b4b4)

Tff7b72if Tff7b72not Te6edf3is_newTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffDuplicate message received on channel Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_EXTREMETb4b4b4)
Tff7b72return
Tff7b72elseTb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Te6edf3contigous Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3e Tff7b72in Tff7b72selfTff7b72.Td2a8ff_rx_ringTb4b4b4:
Tff7b72if Te6edf3eTff7b72.Td2a8ffsequence Tff7b72== Tff7b72selfTff7b72.Td2a8ff_next_rx_sequenceTb4b4b4:
Te6edf3contigousTff7b72.Td2a8ffappendTb4b4b4(Te6edf3eTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_next_rx_sequence Tff7b72= Tb4b4b4(Tff7b72selfTff7b72.Td2a8ff_next_rx_sequence Tff7b72+ T79c0ff1Tb4b4b4) Tff7b72% Te6edf3ChannelTff7b72.Td2a8ffSEQ_MODULUS
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_next_rx_sequence Tff7b72== T79c0ff0Tb4b4b4:
Tff7b72for Te6edf3e Tff7b72in Tff7b72selfTff7b72.Td2a8ff_rx_ringTb4b4b4:
Tff7b72if Te6edf3eTff7b72.Td2a8ffsequence Tff7b72== Tff7b72selfTff7b72.Td2a8ff_next_rx_sequenceTb4b4b4:
Te6edf3contigousTff7b72.Td2a8ffappendTb4b4b4(Te6edf3eTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_next_rx_sequence Tff7b72= Tb4b4b4(Tff7b72selfTff7b72.Td2a8ff_next_rx_sequence Tff7b72+ T79c0ff1Tb4b4b4) Tff7b72% Te6edf3ChannelTff7b72.Td2a8ffSEQ_MODULUS

Tff7b72for Te6edf3e Tff7b72in Te6edf3contigousTb4b4b4:
Tff7b72if Tff7b72not Te6edf3eTff7b72.Td2a8ffunpackedTb4b4b4:
Te6edf3m Tff7b72= Te6edf3eTff7b72.Td2a8ffunpackTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_message_factoriesTb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3m Tff7b72= Te6edf3eTff7b72.Td2a8ffmessage
Tff7b72selfTff7b72.Td2a8ff_rx_ringTff7b72.Td2a8ffremoveTb4b4b4(Te6edf3eTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_run_callbacksTb4b4b4(Te6edf3mTb4b4b4)

Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffAn error ocurred while receiving data on Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff. The contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Tff7b72def Td2a8ffis_ready_to_sendTb4b4b4(Tff7b72selfTb4b4b4) Tff7b72-Tff7b72> Tffa657boolTb4b4b4:
T8b949e"""
Check if ``Channel`` is ready to send.

:return: True if ready
"""
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ff_outletTff7b72.Td2a8ffis_usableTb4b4b4:
Tff7b72return Tff7b72False

Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Te6edf3outstanding Tff7b72= T79c0ff0
Tff7b72for Te6edf3envelope Tff7b72in Tff7b72selfTff7b72.Td2a8ff_tx_ringTb4b4b4:
Tff7b72if Te6edf3envelopeTff7b72.Td2a8ffoutlet Tff7b72== Tff7b72selfTff7b72.Td2a8ff_outletTb4b4b4:
Tff7b72if Tff7b72not Te6edf3envelopeTff7b72.Td2a8ffpacket Tff7b72or Tff7b72not Tff7b72selfTff7b72.Td2a8ff_outletTff7b72.Td2a8ffget_packet_stateTb4b4b4(Te6edf3envelopeTff7b72.Td2a8ffpacketTb4b4b4) Tff7b72== Te6edf3MessageStateTff7b72.Td2a8ffMSGSTATE_DELIVEREDTb4b4b4:
Te6edf3outstanding Tff7b72+Tff7b72= T79c0ff1

Tff7b72if Te6edf3outstanding Tff7b72>Tff7b72= Tff7b72selfTff7b72.Td2a8ffwindowTb4b4b4:
Tff7b72return Tff7b72False

Tff7b72return Tff7b72True

Tff7b72def Td2a8ff_packet_tx_opTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3packetTb4b4b4: Te6edf3TPacketTb4b4b4, Te6edf3opTb4b4b4: Te6edf3CallableTb4b4b4[Tb4b4b4[Te6edf3TPacketTb4b4b4]Tb4b4b4, Tffa657boolTb4b4b4]Tb4b4b4)Tb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Te6edf3envelope Tff7b72= Tffa657nextTb4b4b4(Tffa657filterTb4b4b4(Tff7b72lambda Te6edf3eTb4b4b4: Tff7b72selfTff7b72.Td2a8ff_outletTff7b72.Td2a8ffget_packet_idTb4b4b4(Te6edf3eTff7b72.Td2a8ffpacketTb4b4b4) Tff7b72== Tff7b72selfTff7b72.Td2a8ff_outletTff7b72.Td2a8ffget_packet_idTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4,
Tff7b72selfTff7b72.Td2a8ff_tx_ringTb4b4b4)Tb4b4b4, Tff7b72NoneTb4b4b4)

Tff7b72if Te6edf3envelope Tff7b72and Te6edf3opTb4b4b4(Te6edf3envelopeTb4b4b4)Tb4b4b4:
Te6edf3envelopeTff7b72.Td2a8fftracked Tff7b72= Tff7b72False
Tff7b72if Te6edf3envelope Tff7b72in Tff7b72selfTff7b72.Td2a8ff_tx_ringTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_tx_ringTff7b72.Td2a8ffremoveTb4b4b4(Te6edf3envelopeTb4b4b4)

Tff7b72if Tff7b72selfTff7b72.Td2a8ffwindow Tff7b72< Tff7b72selfTff7b72.Td2a8ffwindow_maxTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffwindow Tff7b72+Tff7b72= T79c0ff1

T8b949e# TODO: Remove at some point
T8b949e# RNS.log("Increased "+str(self)+" window to "+str(self.window), RNS.LOG_DEBUG)

Tff7b72if Tff7b72selfTff7b72.Td2a8ff_outletTff7b72.Td2a8ffrtt Tff7b72!= T79c0ff0Tb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_outletTff7b72.Td2a8ffrtt Tff7b72> Te6edf3ChannelTff7b72.Td2a8ffRTT_FASTTb4b4b4:
Tff7b72selfTff7b72.Td2a8fffast_rate_rounds Tff7b72= T79c0ff0

Tff7b72if Tff7b72selfTff7b72.Td2a8ff_outletTff7b72.Td2a8ffrtt Tff7b72> Te6edf3ChannelTff7b72.Td2a8ffRTT_MEDIUMTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffmedium_rate_rounds Tff7b72= T79c0ff0

Tff7b72elseTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffmedium_rate_rounds Tff7b72+Tff7b72= T79c0ff1
Tff7b72if Tff7b72selfTff7b72.Td2a8ffwindow_max Tff7b72< Te6edf3ChannelTff7b72.Td2a8ffWINDOW_MAX_MEDIUM Tff7b72and Tff7b72selfTff7b72.Td2a8ffmedium_rate_rounds Tff7b72== Te6edf3ChannelTff7b72.Td2a8ffFAST_RATE_THRESHOLDTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffwindow_max Tff7b72= Te6edf3ChannelTff7b72.Td2a8ffWINDOW_MAX_MEDIUM
Tff7b72selfTff7b72.Td2a8ffwindow_min Tff7b72= Te6edf3ChannelTff7b72.Td2a8ffWINDOW_MIN_LIMIT_MEDIUM
T8b949e# TODO: Remove at some point
T8b949e# RNS.log("Increased "+str(self)+" max window to "+str(self.window_max), RNS.LOG_DEBUG)
T8b949e# RNS.log("Increased "+str(self)+" min window to "+str(self.window_min), RNS.LOG_DEBUG)
Tff7b72elseTb4b4b4:
Tff7b72selfTff7b72.Td2a8fffast_rate_rounds Tff7b72+Tff7b72= T79c0ff1
Tff7b72if Tff7b72selfTff7b72.Td2a8ffwindow_max Tff7b72< Te6edf3ChannelTff7b72.Td2a8ffWINDOW_MAX_FAST Tff7b72and Tff7b72selfTff7b72.Td2a8fffast_rate_rounds Tff7b72== Te6edf3ChannelTff7b72.Td2a8ffFAST_RATE_THRESHOLDTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffwindow_max Tff7b72= Te6edf3ChannelTff7b72.Td2a8ffWINDOW_MAX_FAST
Tff7b72selfTff7b72.Td2a8ffwindow_min Tff7b72= Te6edf3ChannelTff7b72.Td2a8ffWINDOW_MIN_LIMIT_FAST
T8b949e# TODO: Remove at some point
T8b949e# RNS.log("Increased "+str(self)+" max window to "+str(self.window_max), RNS.LOG_DEBUG)
T8b949e# RNS.log("Increased "+str(self)+" min window to "+str(self.window_min), RNS.LOG_DEBUG)


Tff7b72elseTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffEnvelope not found in TX ring for Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_EXTREMETb4b4b4)
Tff7b72if Tff7b72not Te6edf3envelopeTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffSpurious message received on Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_EXTREMETb4b4b4)

Tff7b72def Td2a8ff_packet_deliveredTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3packetTb4b4b4: Te6edf3TPacketTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_packet_tx_opTb4b4b4(Te6edf3packetTb4b4b4, Tff7b72lambda Te6edf3envTb4b4b4: Tff7b72TrueTb4b4b4)

Tff7b72def Td2a8ff_update_packet_timeoutsTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72for Te6edf3envelope Tff7b72in Tff7b72selfTff7b72.Td2a8ff_tx_ringTb4b4b4:
Te6edf3updated_timeout Tff7b72= Tff7b72selfTff7b72.Td2a8ff_get_packet_timeout_timeTb4b4b4(Te6edf3envelopeTff7b72.Td2a8fftriesTb4b4b4)
Tff7b72if Te6edf3envelopeTff7b72.Td2a8ffpacket Tff7b72and Tffa657hasattrTb4b4b4(Te6edf3envelopeTff7b72.Td2a8ffpacketTb4b4b4, Ta5d6ff"Ta5d6ffreceiptTa5d6ff"Tb4b4b4) Tff7b72and Te6edf3envelopeTff7b72.Td2a8ffpacketTff7b72.Td2a8ffreceipt Tff7b72and Te6edf3envelopeTff7b72.Td2a8ffpacketTff7b72.Td2a8ffreceiptTff7b72.Td2a8fftimeoutTb4b4b4:
Tff7b72if Te6edf3updated_timeout Tff7b72> Te6edf3envelopeTff7b72.Td2a8ffpacketTff7b72.Td2a8ffreceiptTff7b72.Td2a8fftimeoutTb4b4b4:
Te6edf3envelopeTff7b72.Td2a8ffpacketTff7b72.Td2a8ffreceiptTff7b72.Td2a8ffset_timeoutTb4b4b4(Te6edf3updated_timeoutTb4b4b4)

Tff7b72def Td2a8ff_get_packet_timeout_timeTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3triesTb4b4b4: Tffa657intTb4b4b4) Tff7b72-Tff7b72> Tffa657floatTb4b4b4:
Te6edf3to Tff7b72= Tffa657powTb4b4b4(T79c0ff1.5Tb4b4b4, Te6edf3tries Tff7b72- T79c0ff1Tb4b4b4) Tff7b72* Tffa657maxTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_outletTff7b72.Td2a8ffrttTff7b72*T79c0ff2.5Tb4b4b4, T79c0ff0.025Tb4b4b4) Tff7b72* Tb4b4b4(Tffa657lenTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_tx_ringTb4b4b4)Tff7b72+T79c0ff1.5Tb4b4b4)
Tff7b72return Te6edf3to

Tff7b72def Td2a8ff_packet_timeoutTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3packetTb4b4b4: Te6edf3TPacketTb4b4b4)Tb4b4b4:
Tff7b72def Td2a8ffretry_envelopeTb4b4b4(Te6edf3envelopeTb4b4b4: Te6edf3EnvelopeTb4b4b4) Tff7b72-Tff7b72> Tffa657boolTb4b4b4:
Tff7b72if Te6edf3envelopeTff7b72.Td2a8fftries Tff7b72>Tff7b72= Tff7b72selfTff7b72.Td2a8ff_max_triesTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffRetry count exceeded on Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff, tearing down Link.Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_shutdownTb4b4b4(Tb4b4b4) T8b949e# start on separate thread?
Tff7b72selfTff7b72.Td2a8ff_outletTff7b72.Td2a8fftimed_outTb4b4b4(Tb4b4b4)
Tff7b72return Tff7b72True

Te6edf3envelopeTff7b72.Td2a8fftries Tff7b72+Tff7b72= T79c0ff1
Tff7b72selfTff7b72.Td2a8ff_outletTff7b72.Td2a8ffresendTb4b4b4(Te6edf3envelopeTff7b72.Td2a8ffpacketTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_outletTff7b72.Td2a8ffset_packet_delivered_callbackTb4b4b4(Te6edf3envelopeTff7b72.Td2a8ffpacketTb4b4b4, Tff7b72selfTff7b72.Td2a8ff_packet_deliveredTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_outletTff7b72.Td2a8ffset_packet_timeout_callbackTb4b4b4(Te6edf3envelopeTff7b72.Td2a8ffpacketTb4b4b4, Tff7b72selfTff7b72.Td2a8ff_packet_timeoutTb4b4b4, Tff7b72selfTff7b72.Td2a8ff_get_packet_timeout_timeTb4b4b4(Te6edf3envelopeTff7b72.Td2a8fftriesTb4b4b4)Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_update_packet_timeoutsTb4b4b4(Tb4b4b4)

Tff7b72if Tff7b72selfTff7b72.Td2a8ffwindow Tff7b72> Tff7b72selfTff7b72.Td2a8ffwindow_minTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffwindow Tff7b72-Tff7b72= T79c0ff1
T8b949e# TODO: Remove at some point
T8b949e# RNS.log("Decreased "+str(self)+" window to "+str(self.window), RNS.LOG_DEBUG)

Tff7b72if Tff7b72selfTff7b72.Td2a8ffwindow_max Tff7b72> Tb4b4b4(Tff7b72selfTff7b72.Td2a8ffwindow_minTff7b72+Tff7b72selfTff7b72.Td2a8ffwindow_flexibilityTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffwindow_max Tff7b72-Tff7b72= T79c0ff1
T8b949e# TODO: Remove at some point
T8b949e# RNS.log("Decreased "+str(self)+" max window to "+str(self.window_max), RNS.LOG_DEBUG)

T8b949e# TODO: Remove at some point
T8b949e# RNS.log("Decreased "+str(self)+" window to "+str(self.window), RNS.LOG_EXTREME)

Tff7b72return Tff7b72False

Tff7b72if Tff7b72selfTff7b72.Td2a8ff_outletTff7b72.Td2a8ffget_packet_stateTb4b4b4(Te6edf3packetTb4b4b4) Tff7b72!= Te6edf3MessageStateTff7b72.Td2a8ffMSGSTATE_DELIVEREDTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_packet_tx_opTb4b4b4(Te6edf3packetTb4b4b4, Te6edf3retry_envelopeTb4b4b4)

Tff7b72def Td2a8ffsendTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3messageTb4b4b4: Te6edf3MessageBaseTb4b4b4) Tff7b72-Tff7b72> Te6edf3EnvelopeTb4b4b4:
T8b949e"""
Send a message. If a message send is attempted and
``Channel`` is not ready, an exception is thrown.

:param message: an instance of a ``MessageBase`` subclass
"""
Te6edf3envelopeTb4b4b4: Te6edf3Envelope Tff7b72| Tff7b72None Tff7b72= Tff7b72None
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffis_ready_to_sendTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72raise Te6edf3ChannelExceptionTb4b4b4(Te6edf3CETypeTff7b72.Td2a8ffME_LINK_NOT_READYTb4b4b4, Ta5d6fffTa5d6ff"Ta5d6ffLink is not readyTa5d6ff"Tb4b4b4)
Te6edf3envelope Tff7b72= Te6edf3EnvelopeTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_outletTb4b4b4, Te6edf3messageTff7b72=Te6edf3messageTb4b4b4, Te6edf3sequenceTff7b72=Tff7b72selfTff7b72.Td2a8ff_next_sequenceTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_next_sequence Tff7b72= Tb4b4b4(Tff7b72selfTff7b72.Td2a8ff_next_sequence Tff7b72+ T79c0ff1Tb4b4b4) Tff7b72% Te6edf3ChannelTff7b72.Td2a8ffSEQ_MODULUS
Tff7b72selfTff7b72.Td2a8ff_emplace_envelopeTb4b4b4(Te6edf3envelopeTb4b4b4, Tff7b72selfTff7b72.Td2a8ff_tx_ringTb4b4b4)

Tff7b72if Te6edf3envelope Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72raise Tf85149BlockingIOErrorTb4b4b4(Tb4b4b4)

Te6edf3envelopeTff7b72.Td2a8ffpackTb4b4b4(Tb4b4b4)
Tff7b72if Tffa657lenTb4b4b4(Te6edf3envelopeTff7b72.Td2a8ffrawTb4b4b4) Tff7b72> Tff7b72selfTff7b72.Td2a8ff_outletTff7b72.Td2a8ffmduTb4b4b4:
Tff7b72raise Te6edf3ChannelExceptionTb4b4b4(Te6edf3CETypeTff7b72.Td2a8ffME_TOO_BIGTb4b4b4, Ta5d6fffTa5d6ff"Ta5d6ffPacked message too big for packet: Tffd700{Tffa657lenTb4b4b4(Te6edf3envelopeTff7b72.Td2a8ffrawTb4b4b4)Tffd700}Ta5d6ff > Tffd700{Tff7b72selfTff7b72.Td2a8ff_outletTff7b72.Td2a8ffmduTffd700}Ta5d6ff"Tb4b4b4)
Te6edf3envelopeTff7b72.Td2a8ffpacket Tff7b72= Tff7b72selfTff7b72.Td2a8ff_outletTff7b72.Td2a8ffsendTb4b4b4(Te6edf3envelopeTff7b72.Td2a8ffrawTb4b4b4)
Te6edf3envelopeTff7b72.Td2a8fftries Tff7b72+Tff7b72= T79c0ff1
Tff7b72selfTff7b72.Td2a8ff_outletTff7b72.Td2a8ffset_packet_delivered_callbackTb4b4b4(Te6edf3envelopeTff7b72.Td2a8ffpacketTb4b4b4, Tff7b72selfTff7b72.Td2a8ff_packet_deliveredTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_outletTff7b72.Td2a8ffset_packet_timeout_callbackTb4b4b4(Te6edf3envelopeTff7b72.Td2a8ffpacketTb4b4b4, Tff7b72selfTff7b72.Td2a8ff_packet_timeoutTb4b4b4, Tff7b72selfTff7b72.Td2a8ff_get_packet_timeout_timeTb4b4b4(Te6edf3envelopeTff7b72.Td2a8fftriesTb4b4b4)Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_update_packet_timeoutsTb4b4b4(Tb4b4b4)

Tff7b72return Te6edf3envelope

Tf0883e@property
Tff7b72def Td2a8ffmduTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""
Maximum Data Unit: the number of bytes available
for a message to consume in a single send. This
value is adjusted from the ``Link`` MDU to accommodate
message header information.

:return: number of bytes available
"""
Te6edf3mdu Tff7b72= Tff7b72selfTff7b72.Td2a8ff_outletTff7b72.Td2a8ffmdu Tff7b72- T79c0ff6 T8b949e# sizeof(msgtype) + sizeof(length) + sizeof(sequence)
Tff7b72if Te6edf3mdu Tff7b72> T79c0ff0xFFFFTb4b4b4:
Te6edf3mdu Tff7b72= T79c0ff0xFFFF
Tff7b72return Te6edf3mdu


Tff7b72class T56d364LinkChannelOutletTb4b4b4(Te6edf3ChannelOutletBaseTb4b4b4)Tb4b4b4:
T8b949e"""
An implementation of ChannelOutletBase for RNS.Link.
Allows Channel to send packets over an RNS Link with
Packets.

:param link: RNS Link to wrap
"""
Tff7b72def Tff7b72__init__Tb4b4b4(Tff7b72selfTb4b4b4, Te6edf3linkTb4b4b4: Te6edf3RNSTff7b72.Td2a8ffLinkTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8fflink Tff7b72= Te6edf3link

Tff7b72def Td2a8ffsendTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3rawTb4b4b4: Tffa657bytesTb4b4b4) Tff7b72-Tff7b72> Te6edf3RNSTff7b72.Td2a8ffPacketTb4b4b4:
Te6edf3packet Tff7b72= Te6edf3RNSTff7b72.Td2a8ffPacketTb4b4b4(Tff7b72selfTff7b72.Td2a8fflinkTb4b4b4, Te6edf3rawTb4b4b4, Te6edf3contextTff7b72=Te6edf3RNSTff7b72.Td2a8ffPacketTff7b72.Td2a8ffCHANNELTb4b4b4)
Tff7b72if Tff7b72selfTff7b72.Td2a8fflinkTff7b72.Td2a8ffstatus Tff7b72== Te6edf3RNSTff7b72.Td2a8ffLinkTff7b72.Td2a8ffACTIVETb4b4b4:
Te6edf3packetTff7b72.Td2a8ffsendTb4b4b4(Tb4b4b4)
Tff7b72return Te6edf3packet

Tff7b72def Td2a8ffresendTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3packetTb4b4b4: Te6edf3RNSTff7b72.Td2a8ffPacketTb4b4b4) Tff7b72-Tff7b72> Te6edf3RNSTff7b72.Td2a8ffPacketTb4b4b4:
Te6edf3receipt Tff7b72= Te6edf3packetTff7b72.Td2a8ffresendTb4b4b4(Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3receiptTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffFailed to resend packetTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72return Te6edf3packet

Tf0883e@property
Tff7b72def Td2a8ffmduTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8fflinkTff7b72.Td2a8ffmdu

Tf0883e@property
Tff7b72def Td2a8ffrttTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8fflinkTff7b72.Td2a8ffrtt

Tf0883e@property
Tff7b72def Td2a8ffis_usableTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72True T8b949e# had issues looking at Link.status

Tff7b72def Td2a8ffget_packet_stateTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3packetTb4b4b4: Te6edf3TPacketTb4b4b4) Tff7b72-Tff7b72> Te6edf3MessageStateTb4b4b4:
Tff7b72if Te6edf3packetTff7b72.Td2a8ffreceipt Tff7b72== Tff7b72NoneTb4b4b4:
Tff7b72return Te6edf3MessageStateTff7b72.Td2a8ffMSGSTATE_FAILED

Te6edf3status Tff7b72= Te6edf3packetTff7b72.Td2a8ffreceiptTff7b72.Td2a8ffget_statusTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3status Tff7b72== Te6edf3RNSTff7b72.Td2a8ffPacketReceiptTff7b72.Td2a8ffSENTTb4b4b4:
Tff7b72return Te6edf3MessageStateTff7b72.Td2a8ffMSGSTATE_SENT
Tff7b72if Te6edf3status Tff7b72== Te6edf3RNSTff7b72.Td2a8ffPacketReceiptTff7b72.Td2a8ffDELIVEREDTb4b4b4:
Tff7b72return Te6edf3MessageStateTff7b72.Td2a8ffMSGSTATE_DELIVERED
Tff7b72if Te6edf3status Tff7b72== Te6edf3RNSTff7b72.Td2a8ffPacketReceiptTff7b72.Td2a8ffFAILEDTb4b4b4:
Tff7b72return Te6edf3MessageStateTff7b72.Td2a8ffMSGSTATE_FAILED
Tff7b72elseTb4b4b4:
Tff7b72raise Tf85149ExceptionTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffUnexpected receipt state: Tffd700{Te6edf3statusTffd700}Ta5d6ff"Tb4b4b4)

Tff7b72def Td2a8fftimed_outTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8fflinkTff7b72.Td2a8ffteardownTb4b4b4(Tb4b4b4)

Tff7b72def Tff7b72__str__Tb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72return Ta5d6fffTa5d6ff"Tffd700{Tff7b72selfTff7b72.Td2a8ff__class__Tff7b72.Td2a8ff__name__Tffd700}Ta5d6ff(Tffd700{Tff7b72selfTff7b72.Td2a8fflinkTffd700}Ta5d6ff)Ta5d6ff"

Tff7b72def Td2a8ffset_packet_timeout_callbackTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3packetTb4b4b4: Te6edf3RNSTff7b72.Td2a8ffPacketTb4b4b4, Te6edf3callbackTb4b4b4: Te6edf3CallableTb4b4b4[Tb4b4b4[Te6edf3RNSTff7b72.Td2a8ffPacketTb4b4b4]Tb4b4b4, Tff7b72NoneTb4b4b4] Tff7b72| Tff7b72NoneTb4b4b4,
Te6edf3timeoutTb4b4b4: Tffa657float Tff7b72| Tff7b72None Tff7b72= Tff7b72NoneTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3timeout Tff7b72and Te6edf3packetTff7b72.Td2a8ffreceiptTb4b4b4:
Te6edf3packetTff7b72.Td2a8ffreceiptTff7b72.Td2a8ffset_timeoutTb4b4b4(Te6edf3timeoutTb4b4b4)

Tff7b72def Td2a8ffinnerTb4b4b4(Te6edf3receiptTb4b4b4: Te6edf3RNSTff7b72.Td2a8ffPacketReceiptTb4b4b4)Tb4b4b4:
Te6edf3callbackTb4b4b4(Te6edf3packetTb4b4b4)

Tff7b72if Te6edf3packet Tff7b72and Te6edf3packetTff7b72.Td2a8ffreceiptTb4b4b4:
Te6edf3packetTff7b72.Td2a8ffreceiptTff7b72.Td2a8ffset_timeout_callbackTb4b4b4(Te6edf3inner Tff7b72if Te6edf3callback Tff7b72else Tff7b72NoneTb4b4b4)

Tff7b72def Td2a8ffset_packet_delivered_callbackTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3packetTb4b4b4: Te6edf3RNSTff7b72.Td2a8ffPacketTb4b4b4, Te6edf3callbackTb4b4b4: Te6edf3CallableTb4b4b4[Tb4b4b4[Te6edf3RNSTff7b72.Td2a8ffPacketTb4b4b4]Tb4b4b4, Tff7b72NoneTb4b4b4] Tff7b72| Tff7b72NoneTb4b4b4)Tb4b4b4:
Tff7b72def Td2a8ffinnerTb4b4b4(Te6edf3receiptTb4b4b4: Te6edf3RNSTff7b72.Td2a8ffPacketReceiptTb4b4b4)Tb4b4b4:
Te6edf3callbackTb4b4b4(Te6edf3packetTb4b4b4)

Tff7b72if Te6edf3packet Tff7b72and Te6edf3packetTff7b72.Td2a8ffreceiptTb4b4b4:
Te6edf3packetTff7b72.Td2a8ffreceiptTff7b72.Td2a8ffset_delivery_callbackTb4b4b4(Te6edf3inner Tff7b72if Te6edf3callback Tff7b72else Tff7b72NoneTb4b4b4)

Tff7b72def Td2a8ffget_packet_idTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3packetTb4b4b4: Te6edf3RNSTff7b72.Td2a8ffPacketTb4b4b4) Tff7b72-Tff7b72> Tffa657anyTb4b4b4:
Tff7b72if Te6edf3packet Tff7b72and Tffa657hasattrTb4b4b4(Te6edf3packetTb4b4b4, Ta5d6ff"Ta5d6ffget_hashTa5d6ff"Tb4b4b4) Tff7b72and Tffa657callableTb4b4b4(Te6edf3packetTff7b72.Td2a8ffget_hashTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3packetTff7b72.Td2a8ffget_hashTb4b4b4(Tb4b4b4)
Tff7b72elseTb4b4b4:
Tff7b72return Tff7b72None


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────